package red.mlz.module.module.game.service;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import red.mlz.module.module.category.entity.Category;
import red.mlz.module.module.category.service.CategoryService;
import red.mlz.module.module.game.entity.Game;
import red.mlz.module.module.game.mapper.GameMapper;
import red.mlz.module.module.game.request.GameDescriptionDto;
import red.mlz.module.module.gametagrelation.entity.GameTagRelation;
import red.mlz.module.module.gametagrelation.service.GameTagRelationService;
import red.mlz.module.module.tag.service.TagService;

import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GameService {
    @Autowired
    private GameMapper gameMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private TagService tagService;
    @Autowired
    private GameTagRelationService gameTagRelationService;

    public Integer getTotalGames() {
        return gameMapper.getTotalRecode();
    }

    public List<Game> getAllGames(Integer page, Integer pageSize, String keyword) {
        log.info("查询游戏列表 - page:{}, pageSize:{}, keyword:{}", page, pageSize, keyword);

        // 获取分类ID列表
        List<BigInteger> categoryIds = categoryService.getCategoryIdByKeyword(keyword);
        String ids = categoryIds.stream()
                .map(BigInteger::toString)
                .collect(Collectors.joining(","));

        // 计算偏移量
        int offset = (page - 1) * pageSize;

        try {
            List<Game> result = gameMapper.findAll(offset, pageSize, keyword, ids);
            log.info("成功查询到{}条游戏记录", result.size());
            return result;
        } catch (Exception e) {
            log.error("查询游戏列表失败", e);
            throw new RuntimeException("查询游戏列表失败，请稍后重试");
        }
    }

    public Game getById(Long gameId) {

        Game game = gameMapper.getById(gameId);
        if (game == null ) {
            throw new RuntimeException("gameId对应记录不存在");
        }

        return gameMapper.getById(gameId);
    }

    /*//根据gameId进行连表查询
    public GameDTO getGameDTOById(Long gameId) {
        GameDTO gameDTO= gameMapper.getGameDTOById(gameId);
        if (gameDTO == null) {
            throw new RuntimeException("gameId对应记录不存在");
        }
        return gameDTO;
    }

     */
    @Transactional(rollbackFor = Exception.class)
    public Long edit(Long gameId, String gameName, Long playerNumber,
                     String title, String coverImages, String releaseDate, Float price,
                     Long categoryId, String gameDescription, Float rating, String tags) {

        validateParameters(gameId, gameName, title, releaseDate, categoryId, gameDescription, price, rating);

        try {
            List<GameDescriptionDto> checkDescriptions = JSON.parseArray(gameDescription, GameDescriptionDto.class);
            for (GameDescriptionDto checkDescription : checkDescriptions) {
                if (!GameDefine.isArticleContentType(checkDescription.getType())){
                    throw new RuntimeException("游戏详情错误");
                }
            }
        }catch (Exception cause) {
            throw new RuntimeException("游戏详情错误");
        }

        // 处理标签
        List<Long> tagIds = tagService.processTags(tags);

        int timestamp = (int) (System.currentTimeMillis() / 1000);
        Game game = new Game();
        game.setGameName(gameName.trim());
        game.setPlayerNumber(playerNumber);
        game.setTitle(title.trim());
        game.setCategoryId(categoryId);
        game.setGameDescription(gameDescription);
        game.setRating(rating);
        game.setReleaseDate(releaseDate.trim());
        game.setPrice(price);
        game.setCoverImages(coverImages);

        if (gameId != null ) {
            // 更新操作
            game.setId(gameId);
            // 校验ID是否存在
            Game game1 = gameMapper.getById(gameId);
            if (game1 == null ) {
                throw new RuntimeException("gameId对应的记录不存在");
            }

            game.setUpdateTime(timestamp);
            gameMapper.update(game);

            // 智能更新标签关系
            if (!tagIds.isEmpty()) {
                // 获取游戏的所有现有标签关系
                List<GameTagRelation> allExistingRelations = gameTagRelationService.getByGameId(gameId);

                // 找出需要删除的标签(不在新标签列表中)
                List<Long> existingTagIds = allExistingRelations.stream()
                    .map(GameTagRelation::getTagId)
                    .collect(Collectors.toList());
                List<Long> tagsToRemove = existingTagIds.stream()
                    .filter(tagId -> !tagIds.contains(tagId))
                    .collect(Collectors.toList());

                // 找出需要新增的标签(不在现有标签关系中)
                List<Long> tagsToAdd = tagIds.stream()
                    .filter(tagId -> !existingTagIds.contains(tagId))
                    .collect(Collectors.toList());

                // 删除不再需要的标签关系
                tagsToRemove.forEach(tagId -> {
                    GameTagRelation relation = gameTagRelationService.getByGameIdAndTagId(gameId, tagId);
                    if (relation != null) {
                        int result = gameTagRelationService.delete(relation.getId(), timestamp);
                        log.info("Deleted game-tag relation: gameId={}, tagId={}, result={}", 
                            gameId, tagId, result);
                    }
                });

                // 添加新的标签关系
                tagsToAdd.forEach(tagId -> {
                    GameTagRelation relation = new GameTagRelation();
                    relation.setGameId(gameId);
                    relation.setTagId(tagId);
                    relation.setCreateTime(timestamp);
                    relation.setUpdateTime(timestamp);
                    relation.setIsDeleted(0);
                    int result = gameTagRelationService.insert(relation);
                    log.info("Added/restored game-tag relation: gameId={}, tagId={}, result={}",
                        gameId, tagId, result);
                });
            }
            return gameId; // 返回更新的游戏ID
        } else {
            // 新增操作
            game.setCreateTime(timestamp);
            game.setUpdateTime(timestamp);
            game.setIsDeleted(0);
            gameMapper.insert(game);
            // 建立新标签关系
            if (!tagIds.isEmpty()) {
                Long newGameId = game.getId();
                tagIds.forEach(tagId -> {
                    GameTagRelation relation = new GameTagRelation();
                    relation.setGameId(newGameId);
                    relation.setTagId(tagId);
                    relation.setCreateTime(timestamp);
                    relation.setUpdateTime(timestamp);
                    relation.setIsDeleted(0);
                    gameTagRelationService.insert(relation);
                });
            }
            return game.getId();
        }
    }

    private void validateParameters(Long gameId, String gameName, String title,
                                    String releaseDate, Long categoryId, String gameDescription, Float price, Float rating) {
        if (gameName == null || gameName.trim().isEmpty()) {
            throw new RuntimeException("游戏名称不能为空。");
        }
        if (title == null || title.trim().isEmpty()) {
            throw new RuntimeException("标题不能为空。");
        }
        if (releaseDate == null || releaseDate.trim().isEmpty()) {
            throw new RuntimeException("发布日期不能为空。");
        }
        if (categoryId == null ) {
            throw new RuntimeException("游戏类型Id不能为空");
        }
        // 检查categoryId是否存在
        Category category = categoryService.getById(categoryId);
        if (category == null) {
            throw new RuntimeException("游戏类型ID不存在");
        }
        if (gameDescription == null || gameDescription.trim().isEmpty()) {
            throw new RuntimeException("游戏简介不能为空");
        }
        if (price == null || price < 0) {
            throw new RuntimeException("价格不能为空或不能为负数");
        }
        if (rating == null || rating <= 0) {
            throw new RuntimeException("评分不能为空或为负数");
        }
        // 如果gameId为null或小于等于0，并且是在更新操作中，则应该抛出异常
        // 但由于我们在edit方法中已经通过gameId判断了操作类型，这里可以不再校验gameId的具体值
    }



    public int delete(Long gameId) {

        return gameMapper.delete(gameId, (int)(System.currentTimeMillis() / 1000));
    }

    //批量删除
    public List<Game> listDeletedByGameId(List<Long> gameIds) {

        if (gameIds == null ) {
            return Collections.emptyList();
        }
        gameMapper.deleteByIds(gameIds, (int) (System.currentTimeMillis() / 1000));
        return Collections.emptyList();
    }

    public Game extractById(Long gameId) {

        return gameMapper.extractById(gameId);
    }

    public List<Game> findCategoryId(Long categoryId) {
        return gameMapper.findByCategoryId(categoryId);
    }

    public List<Game> getAllGame(Integer page, Integer pageSize, String gameName) {
        return gameMapper.findAllBygame(page,pageSize,gameName);
    }
}
